package com.demo2do.fms.admin.web.controller.supplier.management;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.page.Page;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.resolver.Preloading;
import com.demo2do.core.web.utils.WebUtils;
import com.demo2do.fms.admin.entity.search.supplier.TrailerSearch;
import com.demo2do.fms.admin.entity.security.Login;
import com.demo2do.fms.admin.entity.upload.UploadResult;
import com.demo2do.fms.admin.service.supplier.SupplierService;
import com.demo2do.fms.admin.service.supplier.TrailerService;
import com.demo2do.fms.admin.web.resolver.Secure;
import com.demo2do.fms.entity.supplier.common.Supplier;
import com.demo2do.fms.entity.vehicle.AuditStatus;
import com.demo2do.fms.entity.vehicle.trailer.Trailer;
import com.demo2do.fms.entity.vehicle.trailer.TrailerModifiedVersion;

/**
 * 挂车信息管理
 *
 * @author Ark
 *
 */
@Controller
@RequestMapping("/trailers")
@MenuSetting("menu-supplier")
public class TrailerController {
    
    private static final Logger logger = LoggerFactory.getLogger(TrailerController.class);

    @Autowired
    private TrailerService trailerService;
    
    @Autowired
    private SupplierService supplierService;
    
    /**
     * @param status
     * @param request
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-self-trailer-management")
    public ModelAndView list(@Secure Login login, @RequestParam(name = "status", required = false, defaultValue = "EDITING") AuditStatus status,
                             @RequestParam(name = "trailerUploadResults", required = false) String trailerUploadResults,
                             HttpServletRequest request, Page page) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-list");
        
        int totals = trailerService.count(login, status);
        if (totals > 0) {
            
            List<Trailer> trailers = trailerService.list(login, status, page.with(totals));
            modelAndView.addObject("trailers", trailers);
            
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));
            
        }
        
        modelAndView.addObject("status", status);
        modelAndView.addObject("supplier", login.isSupplier());
        modelAndView.addObject("vam", login.isVam());
        
        if (StringUtils.isNotBlank(trailerUploadResults)) {
            modelAndView.addObject("trailerUploadResults", JsonUtils.parseAsList(trailerUploadResults, UploadResult.class));
        }
        
        return modelAndView;
        
    }
    
    /**
     * 过滤查询panel
     * 
     * @param status
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public ModelAndView search(@RequestParam("status") AuditStatus status) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-search");
        
        modelAndView.addObject("status", status);
        
        return modelAndView;
        
    }
    
    /**
     * 过滤查询
     * 
     * @param search
     * @param request
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-self-trailer-management")
    public ModelAndView onSearch(TrailerSearch search, @Secure Login login, 
                                 HttpServletRequest request, Page page) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-list");
        
        if (login.isSupplier()) {
            search.setSupplierId(login.getSupplierId());
        }
        
        int totals = trailerService.count(search);
        if (totals > 0) {
            
            List<Trailer> trailers = trailerService.search(search, page.with(totals));
            modelAndView.addObject("trailers", trailers);
            
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "filter", "page"));
            
        }
        
        modelAndView.addObject("status", search.getStatus());
        modelAndView.addObject("supplier", login.isSupplier());
        modelAndView.addObject("vam", login.isVam());
        
        return modelAndView;
        
    }
    
    /**
     * 新增挂车 panel
     * 
     * @return
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    @MenuSetting("submenu-self-trailer-management")
    public ModelAndView create() {
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-create");
        return modelAndView;
    }
    
    /**
     * 新增车辆
     * 
     * @param login
     * @param trailer
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onCreate(@Secure Login login, Trailer trailer) {

        HttpResult httpResult = new HttpResult();
        
        try {

            trailerService.create(trailer, login);
            
            httpResult.success().message("创建成功");
            
        } catch (Exception e) {
            logger.error("#onCreate() - create trailer fail, exception is [{}]", e);
            httpResult.fail("500").message("创建失败! " + e.getMessage());
        }
        
        return httpResult;
        
    }
    
    /**
     * 批量上传panel
     * 
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    public ModelAndView upload() {
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-upload");
        return modelAndView;
    }
    
    /**
     * 批量上传
     * 
     * @param login
     * @param file
     * @param attributes
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ModelAndView onUpload(@Secure Login login,
                                 @RequestParam("file") MultipartFile file,
                                 RedirectAttributes attributes) {
        
        ModelAndView modelAndView = new ModelAndView("redirect:/trailers");
        
        // 1. get upload result
        List<UploadResult> vehicleUploadResults = trailerService.upload(file, login);
        
        // 2. set result to redirect_attribute
        if (CollectionUtils.isNotEmpty(vehicleUploadResults) && CollectionUtils.size(vehicleUploadResults) < 20) {
            
            attributes.addAttribute("trailerUploadResults", JsonUtils.toJson(vehicleUploadResults, UploadResult.class));
            
        } else if (CollectionUtils.isNotEmpty(vehicleUploadResults) && CollectionUtils.size(vehicleUploadResults) >= 20) {
            
            vehicleUploadResults = vehicleUploadResults.subList(0, 20);
            attributes.addAttribute("trailerUploadResults", JsonUtils.toJson(vehicleUploadResults, UploadResult.class));
            
        }
        
        return modelAndView;
        
    }
    
    /**
     * 校验牵引车是否已存在
     * 
     * @param brandCNCode
     * @return
     */
    @RequestMapping(value = "/exist", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult exist(@RequestParam(name = "brandCNCode", required = false) String brandCNCode) {
        
        HttpResult httpResult = new HttpResult();
        
        try {

            boolean exist = trailerService.exist(brandCNCode);
            
            httpResult.success().data("exist", exist)
                                .message("查询成功");
            
        } catch (Exception e) {
            logger.error("#exist() - find fail, exception = [{}]", e);
            httpResult.fail("1").message("查询失败," + e.getMessage());
        }
        
        return httpResult;
        
    }
    
    /**
     * 递交审核panel
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/audit", method = RequestMethod.GET)
    public ModelAndView audit(@PathVariable("id") Long id) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-audit");
        
        modelAndView.addObject("id", id);
        
        return modelAndView;
        
    }
    
    /**
     * 递交审核
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/audit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onAudit(@PathVariable("id") Long id, @Secure(property = "id") Long operator) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            Trailer trailer = trailerService.load(Trailer.class, id);
            trailerService.audit(trailer, operator);
            
            httpResult.success().message("递交审核成功");
            
        } catch (Exception e) {
            httpResult.fail("500").message("递交审核失败! " + e.getMessage());
            logger.error("#onAudit() - audit failed, exception=[{}]", e);
        }
        
        return httpResult;
        
    }
    
    /**
     * 批量递交审核panel
     * 
     * @return
     */
    @RequestMapping(value = "/batch-audit", method = RequestMethod.GET)
    public ModelAndView batchAudit() {
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-batch-audit");
        return modelAndView;
    }
    
    /**
     * 递交审核
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/batch-audit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onBatchAudit(@RequestParam("ids") List<Long> ids, @Secure(property = "id") Long operator) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            int failNumber = trailerService.batchAudit(ids, operator);
            
            if (failNumber > 0) {
                httpResult.fail("500").message("批量递交审核成功，成功数量：" + (ids.size() - failNumber) + "，失败数量：" + failNumber);
            } else {
                httpResult.success().message("批量递交审核成功");
            }
            
        } catch (Exception e) {
            httpResult.fail("500").message("批量递交审核失败！" + e.getMessage());
            logger.error("#onAudit() - audit failed, exception=[{}]", e);
        }
        
        return httpResult;
        
    }
    
    /**
     * 车辆变更panel
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/change", method = RequestMethod.GET)
    @MenuSetting("submenu-self-trailer-management")
    public ModelAndView change(@PathVariable("id") Long id) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-change");
        
        Trailer trailer = trailerService.load(Trailer.class, id);
        modelAndView.addObject("trailer", trailer);
        
        TrailerModifiedVersion version = trailerService.prepareChange(trailer);
        modelAndView.addObject("version", version);
        
        return modelAndView;
        
    }
    
    /**
     * 车辆变更
     * 
     * @param operator
     * @param version
     * @return
     */
    @RequestMapping(value = "/{trailerId}/change", method = RequestMethod.POST)
    public ModelAndView onChange(@Secure(property = "id") Long operator,
                                 @Preloading("versionId") TrailerModifiedVersion version) {
        
        ModelAndView modelAndView = new ModelAndView();

        Trailer trailer = trailerService.load(Trailer.class, version.getTrailerId());
        
        try {
            
            trailerService.change(trailer, version, operator);
            
            modelAndView.setViewName("redirect:/trailers?status=MODIFIED");
            
        } catch (BusinessException e) {
            modelAndView.setViewName("supplier/management/trailer/trailer-info-change");
            modelAndView.addObject("errorMessage", e.getMessage());
            modelAndView.addObject("trailer", trailer);
            modelAndView.addObject("version", version);
        }
        
        return modelAndView;
        
    }
    
    /**
     * 转籍panel
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/transfer", method = RequestMethod.GET)
    public ModelAndView transfer(@PathVariable("id") Long id) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-transfer");
        
        Trailer trailer = trailerService.load(Trailer.class, id);
        
        modelAndView.addObject("trailer", trailer);
        
        return modelAndView;
        
    }
    
    /**
     * 转籍
     * 
     * @param id
     * @param operator
     * @return
     */
    @RequestMapping(value = "/{id}/transfer", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onTransfer(@PathVariable("id") Long id, 
                                               @RequestParam("supplierId") Long supplierId, 
                                               @Secure(property = "id") Long operator) {
        
        HttpResult httpResult = new HttpResult();
        
        try {

            Trailer trailer = trailerService.load(Trailer.class, id);
            Supplier supplier = supplierService.load(Supplier.class, supplierId);
            
            trailerService.transfer(trailer, supplier, operator);
            
            httpResult.success().message("转籍成功");
            
        } catch (Exception e) {
            logger.error("#onTransfer() - transfer failed, exception=[{}]", e);
            httpResult.fail("500").message("转籍失败");
        }
        
        return httpResult;
        
    }     
    
    /**
     * 删除车辆panel
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/delete", method = RequestMethod.GET)
    public ModelAndView delete(@PathVariable("id") Long id) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-delete");
        
        modelAndView.addObject("id", id);
        
        return modelAndView;
        
    }
    
    /**
     * 删除车辆
     * 
     * @param id
     * @param operator
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onDelete(@PathVariable("id") Long id, @Secure(property = "id") Long operator) {
        
        HttpResult httpResult = new HttpResult();
        
        try {

            Trailer trailer = trailerService.load(Trailer.class, id);
            trailerService.delete(trailer, operator);
            
            httpResult.success().message("删除成功");
            
        } catch (Exception e) {
            logger.error("#onDelete() - delete failed, exception=[{}]", e);
            httpResult.fail("500").message("删除失败");
        }
        
        return httpResult;
        
    }
    
    /**
     * 车辆转出panel
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/out", method = RequestMethod.GET)
    public ModelAndView out(@PathVariable("id") Long id) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/trailer/trailer-info-out");
        
        modelAndView.addObject("id", id);
        
        return modelAndView;
        
    }
    
    /**
     * 车辆转出
     * 
     * @param id
     * @param operator
     * @return
     */
    @RequestMapping(value = "/{id}/out", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onOut(@PathVariable("id") Long id, @Secure(property = "id") Long operator) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            Trailer trailer = trailerService.load(Trailer.class, id);
            trailerService.out(trailer, operator);
            
            httpResult.success().message("转出成功");
            
        } catch (Exception e) {
            logger.error("#onOut() - out failed, exception=[{}]", e);
            httpResult.fail("500").message("转出失败！" + e.getMessage());
        }
        
        return httpResult;
        
    }
    
}
